#include "cmdcombiner.h"
#include "func/lanefunction.h"

CmdCombiner::CmdCombiner(QObject *parent) :
    QObject(parent)
{
    m_CmdCount=0;
    m_CurrentPointer=0;
}

bool CmdCombiner::appendCmd(const quint8 *Cmd, quint8 nCmdLen)
{
    if ((m_CurrentPointer+nCmdLen+1)>int(sizeof this->m_Cmds))
    {
        return false;
    }
    if (0==nCmdLen)
    {
        return false;
    }
    m_Cmds[m_CurrentPointer]=nCmdLen;
    m_CurrentPointer++;
    memcpy(m_Cmds+m_CurrentPointer, Cmd, nCmdLen);
    m_CurrentPointer+=nCmdLen;
    m_CmdCount++;
    return true;
}

bool CmdCombiner::initialCmd(const QString Cmd)
{
    if (Cmd.length()>MAX_CMD_LEN*2)
    {
        return false;
    }
    quint8 rawCmd[MAX_CMD_LEN];
    if (!hex2Raw(rawCmd, Cmd.toStdString().c_str(), Cmd.length()))
    {
        return false;
    }
    return initialCmd(rawCmd, Cmd.length()/2);
}

bool CmdCombiner::appendCmd(const QString Cmd)
{
    if (Cmd.length()>MAX_CMD_LEN*2)
    {
        return false;
    }
    quint8 rawCmd[MAX_CMD_LEN];
    if (!hex2Raw(rawCmd, Cmd.toStdString().c_str(), Cmd.length()))
    {
        return false;
    }
    return appendCmd(rawCmd, Cmd.length()/2);
}

QString CmdCombiner::toString()
{
    QString sRlt;
    int nCurrentPointer=0;
    for (quint8 nCmdIndex=0; nCmdIndex<this->m_CmdCount; nCmdIndex++)
    {
        char szCmdInHexStr[512+4];
        int nCurrentCmdLen=m_Cmds[nCurrentPointer];
        if (0==nCurrentCmdLen)
        {
            sRlt+=tr("<?>");
            break;
        }
        int nStartIndexOfCmd=nCurrentPointer;
        nCurrentPointer+=(nCurrentCmdLen+1);
        if (nCurrentPointer>=MAX_CMD_GROUP_LEN-2)
        {
            sRlt+=tr("<!>");
            break;
        }
        raw2HexStr(szCmdInHexStr, m_Cmds+nStartIndexOfCmd, nCurrentCmdLen+1);
        sRlt+=tr("<%1>").arg(szCmdInHexStr);
    }
    return sRlt;
}

bool CmdCombiner::verifySW(QString &sErrorMsg, const quint16 expectedSW) const
{
    sErrorMsg.clear();
    int nCurrentPointer=0;
    for (quint8 nCmdIndex=0; nCmdIndex<this->m_CmdCount; nCmdIndex++)
    {
        int nCurrentCmdLen=m_Cmds[nCurrentPointer];
        if ((0==nCurrentCmdLen) || (nCurrentCmdLen+nCurrentPointer>MAX_CMD_GROUP_LEN))
        {
            sErrorMsg=tr("命令结果[%1]长度错误").arg(nCmdIndex);
            return false;
        }
        int sw=getIccSw(m_Cmds+nCurrentPointer);
        if (expectedSW!=sw)
        {
            sErrorMsg=tr("命令结果[%1]状态字[0x%1]错误").arg(nCmdIndex).
                         arg(QString::number(sw, 16));
            return false;
        }
        nCurrentPointer+=(nCurrentCmdLen+1);
    }
    return nCurrentPointer>0;
}
